package com.redis.springbootredis.controller;

import com.redis.springbootredis.entity.Course;
import com.redis.springbootredis.service.impl.CourseServiceImpl;
import com.redis.springbootredis.service.impl.OrderTestServiceImpl;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author
 * @create 2020-10-31 14:27
 */
@RestController
public class MyController {

    @Autowired
    CourseServiceImpl courseService;

    @Autowired
    OrderTestServiceImpl orderTestService;

    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    @Autowired
    RedissonClient redissonClient;

    @Value("${server.port}")
    String port;


    @RequestMapping("/testOne")
    public String testOne(){
        ValueOperations<String, Object> opsForValue = redisTemplate.opsForValue();
        Course course = null;
        if(!redisTemplate.hasKey("course1")){
            System.out.println("数据库查询");
            course = courseService.getCourseByCid(1);
            opsForValue.set("course",course);
        }else{
            System.out.println("缓存查询");
            course =(Course) opsForValue.get("course");
        }
        return course+""+"----:port----"+port;
    }


    //redis是单线程模式，所有是安全的
    @RequestMapping("/incr")
    public String incr(){
        String count = redisTemplate.opsForValue().increment("num").toString();
        return count;
    }

    /*
      单机加锁可以控制安全
      单击加高并发就不安全了
      集群加服务器就不安全了，因为跨越了服务器，锁就管不了了,synchronized只能保证当前虚拟机的安全
      此时为保证数据的安全必须使用分布式锁
    */
    @RequestMapping("/test")
    public synchronized String test(){
        ValueOperations<String, Object> opsForValue = redisTemplate.opsForValue();
        String str = null;
        if(!redisTemplate.hasKey("str")){
            System.out.println("数据库查询");
            str = "abc";
            opsForValue.set("str",str);
        }else{
            System.out.println("缓存");
            str = opsForValue.get("str").toString();
        }
        return str;
    }

    //分布式锁
    @RequestMapping("/locktest")
    public  String locktest(){
        RLock lock = redissonClient.getLock("lock");
        //加锁
        lock.lock();
        ValueOperations<String, Object> opsForValue = redisTemplate.opsForValue();
        String str = null;
        if(!redisTemplate.hasKey("zfc")){
            System.out.println("数据库查询");
            str = "def";
            opsForValue.set("zfc",str);
        }else{
            System.out.println("缓存");
            str = opsForValue.get("zfc").toString();
        }
        //解锁
        lock.unlock();
        return str;
    }

}
